package com.heatup.apt.api.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.framework.service.impl.SuperServiceImpl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.zxing.WriterException;
import com.heatup.apt.api.controller.pay.util.PropertiesUtil;
import com.heatup.apt.api.service.CouponService;
import com.heatup.apt.api.service.DataDictService;
import com.heatup.apt.api.service.ProductServiceInterface;
import com.heatup.apt.api.service.UserService;
import com.heatup.apt.common.constants.ServiceConstans.ServiceType;
import com.heatup.apt.common.constants.TokenConstants;
import com.heatup.apt.common.constants.UserConstants.UserLevel;
import com.heatup.apt.common.constants.UserProductServiceConstants;
import com.heatup.apt.common.dao.*;
import com.heatup.apt.common.dao.coach.CoachInfoMapper;
import com.heatup.apt.common.dao.redis.TokenRedisDao;
import com.heatup.apt.common.dao.redis.UserInfoRedisDao;
import com.heatup.apt.common.dao.store.StoreInfoMapper;
import com.heatup.apt.common.dao.user.UserInfoMapper;
import com.heatup.apt.common.dao.user.UserProductServiceMapper;
import com.heatup.apt.common.dao.user.UserStoreMapper;
import com.heatup.apt.common.dao.user.VipRightsMapper;
import com.heatup.apt.common.util.*;
import com.heatup.apt.model.DataDict;
import com.heatup.apt.model.api.store.StoreResultModel;
import com.heatup.apt.model.coach.CoachInfo;
import com.heatup.apt.model.company.CompanyInfo;
import com.heatup.apt.model.company.CompanyStaff;
import com.heatup.apt.model.coupon.ActivityInfo;
import com.heatup.apt.model.coupon.ActivityUser;
import com.heatup.apt.model.management.SysUser;
import com.heatup.apt.model.order.VipPurchaseLog;
import com.heatup.apt.model.product.ProductService;
import com.heatup.apt.model.product.ServicePrice;
import com.heatup.apt.model.product.ServicePriceExample;
import com.heatup.apt.model.user.ImportVipData;
import com.heatup.apt.model.user.UserInfo;
import com.heatup.apt.model.user.UserProductService;
import com.heatup.apt.model.user.VipRights;
import com.heatup.apt.model.weixin.Token;

import sun.misc.BASE64Encoder;

import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.*;

/**
 * 
 * @author Jindaodaxia
 *
 */
@Service
public class UserServiceImpl  extends SuperServiceImpl<UserInfoMapper, UserInfo> implements UserService {
	
	//邀请有礼对应的活动ID
	public static final Integer ACTIVE_ID = 0;//TODO
    @Resource
    private UserInfoMapper userInfoMapper;
    @Resource
    private ServicePriceMapper servicePriceMapper;
    @Resource
    private VipRightsMapper  vipRightsMapper;
    @Resource
    private ProductServiceInterface productService;
    @Resource
    private ImportVipDataMapper importVipDataMapper;
    @Resource
    private ActivityUserMapper activityUserMapper;
    @Resource
    private CouponService couponService;
    @Resource
    private UserInfoRedisDao userInfoRedisDao;
    @Resource
    private TokenRedisDao tokenRedisDao;
    @Resource
    private ProductServiceMapper productServiceMapper;
    @Resource
    private UserProductServiceMapper userProductServiceMapper;
    @Resource
    private StoreInfoMapper storeInfoMapper;
    @Resource
    private UserStoreMapper userStoreMapper;
    @Resource
    private OrderInfoMapper orderInfoMapper;
    @Resource
    private ActivityInfoMapper activityInfoMapper;
    @Resource
    private CouponDetailMapper couponDetailMapper;
    @Resource
    private TokenMapper tokenMapper;
    @Resource
    private VipPurchaseLogMapper vipPurchaseLogMapper;
    @Resource
    private CoachInfoMapper coachInfoMapper;
    @Resource
    private CompanyStaffMapper companyStaffMapper;
    @Resource
    private CompanyInfoMapper companyInfoMapper;
    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private DataDictService dataDictService;
    
    private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
    
	//获取微信语言
	public static final String LANG = "zh_CN";

    
    @Override
    public UserInfo getUserInfoById(int id) {
       // UserInfo  userInfo= userInfoMapper.selectById(id);
    	 UserInfo  userInfo= userInfoMapper.selectById(id);
        return userInfo;
    }
    
    public static boolean isVip(UserInfo user){
    	if(user.getLevel() >= UserLevel.vip.getIndex()){
    		return true;
    	}else{
    		return false;
    	}
    }

	@Override
	public Map<String, Object> getVipInfoById(int id,int productId,String longitudeLatitude) {
	    Map<String,Object> map = new HashMap<String,Object>();
	    UserInfo user = this.getUserInfoById(id);
	    ProductService productServiceM = productServiceMapper.selectById(productId);
	    if(user == null){
	    	return null;
	    }
	    
        map.put("userid", user.getId());
        map.put("isvip", isVip(user));          
        map.put("level", user.getLevel());
        map.put("headImg",user.getHeadImg());
        map.put("userName",user.getNickName());
        map.put("userAccount",user.getAccountAmt());
        //当前会员起始时间
        if(isVip(user)){
//            map.put("startTime", DateUtil.toDateString(user.getVipStartTime(), DateUtils.datePattern));
            map.put("startTime", DateUtils.toDateString(user.getVipStartTime()));
//            map.put("endTime", DateUtil.formatDate(user.getVipEndTime(), DateUtils.datePattern));  
            map.put("endTime",DateUtils.toDateString(DateUtils.AddDays(user.getVipEndTime(),-1)));
        }else{
        	map.put("startTime", DateUtils.toDateString((new Date())));
            map.put("endTime", DateUtils.toDateString(new Date()));
        }

        //会员1月价格
        ServicePriceExample example = new ServicePriceExample();
        example.or().andServiceTypeEqualTo(ServiceType.vip.getIndex())
        .andLevelEqualTo(UserLevel.vip.getIndex())
        .andDurationEqualTo(1);
        List<ServicePrice> list = servicePriceMapper.selectByExample(example);
        if(list.size()>0){
        	ServicePrice servicePrice = list.get(0);
        	map.put("vipPrice", servicePrice.getPrice().toBigInteger());
        }
        
        //会员权益
      //  List<VipRights> vrlist = this.vipRightsMapper.selectByExample(new VipRightsExample());
        EntityWrapper<VipRights> entityWrapper = new EntityWrapper<VipRights>();
        List<VipRights> vrlist = vipRightsMapper.selectList(entityWrapper);
        List<Map<String,Object>> vrMapList = new ArrayList<Map<String,Object>>();
        
        for(VipRights vipRights : vrlist){
        	Map<String,Object> mapItem = new HashMap<String,Object>();
        	mapItem.put("level", vipRights.getLevel());
        	mapItem.put("selfBuildingPrice", vipRights.getSelfFitnessPrice().toBigInteger());       
        	mapItem.put("course", vipRights.getCourse());
        	vrMapList.add(mapItem);
        }
        // 获取使用门店
        if(productServiceM != null){
        	Map<String,Object> parameMap = new HashMap<>();
        	parameMap.put("userId", id);
        	if(StringUtils.isNotBlank(longitudeLatitude) && longitudeLatitude.split(",").length == 2){
    			parameMap.put("latitude", longitudeLatitude.split(",")[0]);
    			parameMap.put("longitude", longitudeLatitude.split(",")[1]);
            }
        	String[] storStr = productServiceM.getPStoreListLimit().split("#");
        	List<String> listStoreId = java.util.Arrays.asList(storStr);
        	parameMap.put("list", listStoreId);
        	if(productServiceM.getId() == 1 || productServiceM.getPIsStoreListLimit().intValue() == 1){
        		parameMap.remove("list");
        	}
        	parameMap.put("status", 2);

        	//除仅支持私教外的门店
        	List<String> isSelfFintnessList = new ArrayList();
			isSelfFintnessList.add("1");
			isSelfFintnessList.add("0");
			isSelfFintnessList.add("2");
			parameMap.put("isSelfFintnessList",isSelfFintnessList);

        	List<StoreResultModel> storeList = storeInfoMapper.queryAllStore(parameMap);
        	StoreResultModel sr= storeInfoMapper.queryUserStoreByUserId(parameMap);
        	map.put("stortList", storeList);
        	map.put("userStore", sr);
        }
        map.put("list", vrMapList);
        map.put("vipList", productService.getViplist(user.getId(),productId));
        map.put("productService", productServiceM);
		return map;
	}
	
	/**
	 * 实例活动明细map
	 */
	@Override
	public UserInfo wechatLogin(String openid, String nickname, String headimg, String sex) {
		return this.wechatLogin(openid, nickname, headimg, sex, null, null);
	}
	
	public ActivityUser initActiveMap(String userName, Integer userid, Integer invite_userid, Integer activeId) {
		if(userid == null || invite_userid == null) {
			throw new RuntimeException("error in initActiveMap invite_userid is null!!");
		}
		ActivityUser aUser = new ActivityUser();
		aUser.setActivityId(activeId);
		aUser.setCreateBy(userName);
		aUser.setCreateTime(new Date());
		aUser.setInviteUserid(invite_userid);
		aUser.setUserid(userid);
		
		return aUser;
	}

	
	/**
	 * 微信登录 
	 */
	@Override
	public UserInfo wechatLogin(String openid, String nickname, String headimg, String sex, String shareOpenid, String activeId) {
		UserInfo userInfo = null; 
		if(openid != null && openid.length() > 0){
			userInfo = userInfoMapper.selectByOpenid(openid);
		}	
		UserInfo shareUserInfo = null;
		// 如果用户的openId为空的时候就返回一个null
		if(StringUtil.isEmpty(openid)){
			logger.info("================获取不到用户的openid======================================");
			logger.error("================获取不到用户的openid======================================日期："+new Date());
			return userInfo;
		}
		if(userInfo == null){
			//新建用户
			userInfo = new UserInfo();
			userInfo.setNickName(nickname);
			userInfo.setOpenid(openid);
			userInfo.setHeadImg(headimg);
			userInfo.setGender(sex);
			userInfo.setCreatedTime(new Date());
			if(StringUtil.notNull(shareOpenid)) {
				try {
					DesUtils des = new DesUtils(String.valueOf(PropertiesUtil.get("des_key")).trim());
					shareOpenid =  des.decrypt(shareOpenid);
				} catch (Exception e) {
					logger.info(e.getMessage());
				}
				shareUserInfo = userInfoMapper.selectByOpenid(shareOpenid);
				if(shareUserInfo != null) {
					userInfo.setInviterUserid(shareUserInfo.getId());//邀请人openid
				}
			}
			userInfo.setLevel(UserLevel.user.getIndex());
			userInfo.setUpdatedTime((new Date()));
			int bRet = userInfoMapper.insertSelective(userInfo);
			//userInfo = userInfoMapper.selectById(userInfo.getId());
			userInfo = userInfoMapper.selectById(userInfo.getId());
			if(StringUtil.notNull(shareOpenid)) {
//				//给邀请人和被邀请人发放优惠券
//				logger.info(userInfo.getId()+" : user id and shareid value is :"+ shareUserInfo.getId());
				Integer aId = StringUtil.notNull(activeId) ? Integer.parseInt(activeId) : 0;
//				if(aId == 0 || aId == null) {
//					throw new RuntimeException("优惠券已经领完");
//				}
//				couponService.addCouponDetailByActivityId(aId, userInfo.getId());
//				//向活动明细表插入参与活动的人插入数据
//				ActivityUser aUser = this.initActiveMap(nickname, shareUserInfo.getId(),  userInfo.getId(), aId);
//				activityUserMapper.insertSelective(aUser);
				this.sendCounpon(userInfo, aId, shareUserInfo);
			}
			// 判断新用户向用户服务表中插入一条记录
			creadeUserProductService(userInfo.getId());
		}else{
			userInfo.setNickName(nickname);
			userInfo.setOpenid(openid);
			userInfo.setHeadImg(headimg);
			userInfo.setGender(sex);
			userInfo.setUpdatedTime((new Date()));
			userInfo.setUpdatedBy(userInfo.getId());
			if(StringUtil.notNull(shareOpenid)) {
				try {
					DesUtils des = new DesUtils(String.valueOf(PropertiesUtil.get("des_key")).trim());
					shareOpenid =  des.decrypt(shareOpenid);
				} catch (Exception e) {
					logger.info(e.getMessage());
				}
				shareUserInfo = userInfoMapper.selectByOpenid(shareOpenid);
				if(shareUserInfo != null) {
					userInfo.setInviterUserid(shareUserInfo.getId());//邀请人openid
				}
				Integer aId = StringUtil.notNull(activeId) ? Integer.parseInt(activeId) : 0;
				//判断是否需要送券
				Map<String,Object> map = this.isNewCustomOrInsert(openid, userInfo, aId, shareUserInfo);
				
			}
			if(userInfo.getVipEndTime() !=null && userInfo.getLevel()!=UserLevel.user.getIndex()){
				//会员已过期
				if(userInfo.getVipEndTime().before(new Date()) ){
					userInfo.setLevel(UserLevel.user.getIndex());
					/*userInfoMapper.updateByPrimaryKey(userInfo);*/
				}
			}
			//int bool = userInfoMapper.updateByPrimaryKeySelective(userInfo);
			int bool = userInfoMapper.updateSelectiveById(userInfo);
		}
		
		return userInfo;
	}

	
	/**
	 * 获取用户会员服务的结束时间
	 */
	@Override
	public Date getVipEndDate(int userId) {
		//todo:需要从会员记录中计算
		UserInfo  userInfo= userInfoMapper.selectById(userId);
		return userInfo.getVipEndTime();
	}

	/**
	 * 获取下次会员服务的开始时间
	 */
	@Override
	public Date getNextVipStartDate(int userId) {
		Date endDate = getVipEndDate(userId);
		Date startDate = new Date();
		if(endDate != null){
			Calendar calendar = Calendar.getInstance(); 
		    calendar.setTime(endDate); 
		    calendar.add(Calendar.DATE,1);
		    startDate = calendar.getTime(); 
		}

		return startDate;
	}

	/**
	 * 根据会员购买记录,更新用户等级
	 */
	@Override
	public int updateUserLevel(int userId) {
		/*userInfoMapper.updateUserLevel(userId);*/

		UserInfo  userInfo= userInfoMapper.selectById(userId);
		return userInfo.getLevel();
	}

    /**
     * 更新用户表的手机号
     *
     * @param userId 用户ID
     * @param mobile 新手机号
     * @author blank 2017/8/1 下午4:11
     */
    @Override
	public void updateMobile(Integer userId, String mobile) {

        if (userId == null || StringUtil.isEmpty(mobile)) {
            throw new IllegalArgumentException("userId or mobile can not be null !");
        }
        UserInfo userInfo = new UserInfo();
        userInfo.setId(userId);
        userInfo.setMobile(mobile);
        userInfoMapper.updateSelectiveById(userInfo);

    }

    /**
     * 更新用户所有表中的手机号为新手机号
     *
     * @param userId 用户ID
     * @param mobile 新手机号
     * @author blank 2017/8/18 下午4:49
     */
    @Override
    public void syncUserAllMobile(Integer userId, String mobile) {

        if (userId == null || StringUtil.isEmpty(mobile)) {
            throw new IllegalArgumentException("userId or mobile can not be null !");
        }
        UserInfo userInfoDB = userInfoMapper.selectById(userId);

        UserInfo userInfo = new UserInfo();
        userInfo.setId(userId);
        userInfo.setMobile(mobile);
        userInfoMapper.updateSelectiveById(userInfo);

        if (userInfoDB != null && StringUtil.isNotEmpty(userInfoDB.getMobile())) {
            //同时更新教练/企业同一用户的表数据
            CoachInfo coachInfo = new CoachInfo();
            coachInfo.setMobile(mobile);

            CoachInfo coachInfoDB = new CoachInfo();
            coachInfoDB.setMobile(userInfoDB.getMobile());//使用用户旧的手机号替换其原手机号的数据
            coachInfoMapper.updateSelective(coachInfo, coachInfoDB);//教练手机号

            //同时更新企业旧有手机号

            CompanyInfo companyInfo = new CompanyInfo();
            companyInfo.setManagerMobile(mobile);

            CompanyInfo companyInfoDB = new CompanyInfo();
            companyInfoDB.setManagerMobile(userInfoDB.getMobile());
            companyInfoMapper.updateSelective(companyInfo, companyInfoDB);//企业管理手机号

            companyInfo = new CompanyInfo();
            companyInfo.setClientManagerMobile(mobile);

            companyInfoDB = new CompanyInfo();
            companyInfoDB.setClientManagerMobile(userInfoDB.getMobile());
            companyInfoMapper.updateSelective(companyInfo, companyInfoDB);//企业客户经理手机号

            //同时更新企业员工手机号

            CompanyStaff companyStaff = new CompanyStaff();
            companyStaff.setMobile(mobile);

            CompanyStaff companyStaffDB = new CompanyStaff();
            companyStaffDB.setMobile(userInfoDB.getMobile());
            companyStaffMapper.updateSelective(companyStaff, companyStaffDB);//企业员工手机号


            //同时更新系统用户手机号
            sysUserMapper.updateSystemUserMobileByOldMobile(mobile, userInfoDB.getMobile());

        }

    }

    @Override
	public UserInfo getUserByMobile(String mobile) {
		
		List<UserInfo> userInfoList = userInfoMapper.selectUsersByMobile(mobile);
		if(userInfoList.size() == 0 || userInfoList == null){
			return null;
		}
		UserInfo userInfo = userInfoList.get(0);
		return userInfo;
	}
	
	/**
	 * 添加预售会员至用户信息表
	 * 
	 */
	@Override
	public UserInfo updatePresellUser(Map<String, Object> map) {
		logger.info("==============================================binding presell user start =======================================");
		String mobile = (String) map.get("mobile");
		Integer userId = (Integer) map.get("userId");
		//int userId = Integer.valueOf(userIds);
		ImportVipData vipData = importVipDataMapper.queryImportVipDataByMobile(mobile);
		UserInfo userInfo = null;
	    // 1 是预售会员
		logger.info("==============================================binding presell user  ======mobile:"+mobile+"=====userId:"+userId+"============================");
		if(vipData != null){
			userInfo = userInfoMapper.selectById(userId);
			// 并未添加到会员时间
			if(vipData.getImported() == 0){
				Date end_date = null;
				Date start_date = null;
				try {
					// 1 购买过会员
					logger.info("============================================ user level:"+userInfo.getLevel());
					if(userInfo.getLevel() == 2){
						end_date = userInfo.getVipEndTime();
						start_date = userInfo.getVipStartTime();
					}else{
						end_date = DateUtils.getDateShort((new Date()));//DateUtils.toDate(String.valueOf(PropertiesUtil.get("course_pre_sale_date")).trim());
						start_date = DateUtils.getDateShort((new Date()));
					}
					
				} catch (Exception e) {
					e.printStackTrace();
					logger.info("============================================ updatePresellUser error:"+e.getMessage());
				}
				Calendar calendar = Calendar.getInstance();
				calendar.setTime(end_date);
				calendar.add(Calendar.MONTH, vipData.getMonthCount());// 日期加1个月
				if(userInfo.getLevel() == 1){
					calendar.add(Calendar.DATE,1);
				}
				end_date = calendar.getTime();
				userInfo.setVipEndTime(end_date);
				userInfo.setVipStartTime(start_date);
				logger.info("==============================================binding presell user  ======month_count:"+vipData.getMonthCount()+"=====start_date:"+start_date+"===end_date=:"+end_date+"=========================");
			}
			vipData.setImported(1);
			vipData.setUpdateTime((new Date()));
			userInfo.setLevel(2);
			userInfo.setMobile(mobile);
			int bool = userInfoMapper.updateSelectiveById(userInfo);
			int vipBool = importVipDataMapper.updateImportVipData(vipData);
			logger.info("==============================================binding presell user end =========bool:"+bool+"==============================");
		}else{
			userInfo = userInfoMapper.selectById(userId);
			userInfo.setMobile(mobile);
			userInfo.setUpdatedTime((new Date()));
			int bool = userInfoMapper.updateSelectiveById(userInfo);
			logger.info("==============================================This user no presell user update user mobile========bool:"+bool+"======================");
			logger.info("==============================================binding presell user end =====================================================");
			return null;
		}
		return userInfo;
	}
	
	/**
	 * 判断当前用户是否是预售会员并且是已经绑定过的
	 */
	@Override
	public boolean judgeUserInfoIfPresellVip(UserInfo user) {
		Map<String,Object> map = new HashMap<String,Object>();
		boolean bool = true;
		// 未绑定过手机号码
		if(user.getLevel() == 1){
			bool = false;
		}else{
			bool = true;
			/*String mobile = user.getMobile() == null?"":user.getMobile();
			if(mobile.length() == 0 ){
				return true;
			}
			// 查看是否是预售会员
			ImportVipData vipData = importVipDataMapper.queryImportVipDataByMobile(mobile);
			// 不会预售会员
			if(vipData == null){
				bool = false;
			}
			// 是预售会员开通过了
			else if(vipData != null && vipData.getImported() == 1){
				bool = true;
			}
			// 
			else if(vipData != null &&  vipData.getImported() == 0){
				bool = false;
			}*/
		}
		return bool;
	}
    
    /**
     * 根据openid 返回用户信息
     * 
     */
    public UserInfo getUserInfoByOpenId(String openId) {
    	UserInfo userInfo = userInfoMapper.selectByOpenid(openId);
    	return userInfo;
    }
    
    //增加用户的vip天数，从当天开始算起
	public Map<String,Object> addUserVipDayNum(int userId, int dayNum) {
        Map<String,Object> resultMap = new HashMap<>();
		if(dayNum < 0){
			logger.warn("warn: failed to add UserVipDay Count, userId:" + userId +",dayNum:"+dayNum);
			return null;
		}
		UserInfo userInfo = userInfoMapper.selectById(userId);
		
		if (userInfo==null){
			logger.warn("warn: failed not found this user: add UserVipDay Count, userId:" + userId +",dayNum:"+dayNum);
			return null;
		}
		
		Date start_date = DateUtils.getDateShort(new Date());
		Date end_date = null;
		Calendar ca = Calendar.getInstance();
		ca.add(Calendar.DATE, dayNum);// dayNum为增加的天数


		if(userInfo.getLevel()==2){
			start_date = DateUtils.getDateShort(userInfo.getVipEndTime()); //先取用户的vip结束时间
			//原来是会员的，就一定是在原来的基础上增加天数
			end_date = DateUtils.AddDays(start_date, dayNum);  //加上该券的时间
		}else{
			 end_date = DateUtils.getDateShort(ca.getTime());		
			 userInfo.setVipStartTime(start_date);
		}
		
		userInfo.setVipEndTime(end_date);
		userInfo.setUpdatedTime(DateUtils.getDateShort(new Date()));
		userInfo.setLevel(2);
		int bool = userInfoMapper.updateSelectiveById(userInfo);


		UserProductService userProductService = null;
		userProductService = userProductServiceMapper.queryUserProductServiceToUserLevel(userId);
		// 判断该用户是否拥有该服务
		if(userProductService != null){
			// 这里不管用户的身份是否有效这里都要置为会员的有效状态 所以这里就不做过多的判断了
			userProductService.setBeginDate(DateUtils.getDateShort(userInfo.getVipStartTime()));
			userProductService.setEndDate(DateUtils.getDateShort(userInfo.getVipEndTime()));
			userProductService.setUpdatedBy(userInfo.getId());
			userProductService.setUpdatedTime(new Date());
			userProductService.setIsvaild(UserProductServiceConstants.ISVALID);
			userProductService.setProductServiceType(UserProductServiceConstants.productServiceType.vip.getType());

			// 变更信息
			Integer boolU = userProductServiceMapper.updateSelectiveById(userProductService);
			logger.info("================= update userProductService data bool:"+boolU);
		}else{
			// 没有注册过我们平台的用户
			userProductService = new UserProductService();
			userProductService.setBeginDate(DateUtils.getDateShort(userInfo.getVipStartTime()));
			userProductService.setEndDate(DateUtils.getDateShort(userInfo.getVipEndTime()));
			userProductService.setCreatedTime(new Date());
			userProductService.setProductServiceType(UserProductServiceConstants.productServiceType.vip.getType());
			userProductService.setUserId(userInfo.getId());
			userProductService.setCreatedBy(userInfo.getId());
			userProductService.setIsvaild(UserProductServiceConstants.ISVALID);
			Integer boolI = userProductServiceMapper.insertSelective(userProductService);
			logger.info("=================== insert into userProductService data bool:"+boolI);
		}

		logger.info("info: success to add UserVipDay Count, userId:" + userId +",dayNum:"+dayNum);
		resultMap.put("useBeginDate",start_date);
		resultMap.put("useEndDate",end_date);
		resultMap.put("userProductService",userProductService);

		return resultMap;
	}

	@Override
	public int updateUserInfo(UserInfo userInfo) {
		int bool = userInfoMapper.updateSelectiveById(userInfo);
		return bool;
	}
	
	//https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
	//判断用户是否已关注过我们公众号： 1:已关注。0: 未关注。   
	public Integer isSubScribe(String userid){
		try{
			//先查数据库是否已关注过
			UserInfo userInfo =userInfoMapper.selectById(Integer.valueOf(userid));
			if (userInfo == null){
				return 0; //没查到用户，表示没有关注过
			}
			
			Integer subscribe = 1; //默认已关注
			if (userInfo.getSubscribe() == null){
				subscribe=0;
			}else if (userInfo.getSubscribe() == 1){
				return 1; //1表示已关注
			}
			
			//先获取accesstoken
//			String strToken = tokenMapper.selectTokenByKey(TokenConstants.ACCESS_TOKEN_KEY).getToken();
			//从redis获取。
			String strToken = tokenRedisDao.queryTokenByRedis().getToken();
			
			if (StringUtils.isEmpty(strToken)){
				return 1;  //默认已关注
			}
			
	        String urlUserInfo =String.valueOf(PropertiesUtil.get("wechat_userinfo_url")).trim() ; //"https://api.weixin.qq.com/cgi-bin/user/info";
	
	    	Map<String, String> map = new HashMap<String, String>();
	        map.put("openid", userInfo.getOpenid());
	        map.put("access_token", strToken);   
	        map.put("lang", LANG);
	        //urlUserInfo = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=UOdRIUYtRXLXXJ7tC49eyi2GBuEQJvnTi0MvgRkPXaM4jR9skN5WZVx17_gq46kMRhfT8sYWZm01NS0TRvAodFwUigye7KIKimUWainxcn0RLHgAEAHBX&openid=o0r3rwZ6qAMQUDPa0e-NNqFuF9nY&lang=zh_CN";
	        urlUserInfo = urlUserInfo + "?access_token=" + strToken +"&openid=" + userInfo.getOpenid() + "&lang=zh_CN";
	        //maxxiang 这里只能是Get请求，不能用post
	        JSONObject json = JsonClient.post(urlUserInfo, null);
	        if(json == null){
	        	return subscribe;
	        }
	        
	        if(json.containsKey("errcode")){
	       		logger.error("根据第四步的获取用户信息失败openId："+ userInfo.getOpenid()+", errcode:" + json.getString("errcode"));
	        }else{
	        	subscribe = Integer.valueOf(json.get("subscribe").toString());
	        	
	        	if(subscribe == 1){ 
	        		//更新为已关注，以后就可以不用再向微信查询了，提升效率
	        		userInfo.setSubscribe(subscribe);
	        		userInfoMapper.updateSelectiveById(userInfo);
	        	}
	        	return subscribe;
	        }
		}catch(Exception e){
			logger.error("isSubScribe Exception error: " + e.getMessage()); 
		}
        

		return 1;
	}   

	@Override
	public UserInfo queryUserInfoFromRedis(String openId) {
		// TODO Auto-generated method stub
		return userInfoRedisDao.queryUserInfoByOpenIdForm(openId);
	}
	
	/**
	 * 插入用户信息服务表
	 * @param userId
	 */
	public void creadeUserProductService(Integer userId){
		logger.info("======================creadeUserProductService start ======================");
		UserProductService ups1 = userProductServiceMapper.queryUserProductServiceToUserLevel(userId);
		if(ups1 == null){
			try {
				UserProductService ups = new UserProductService();
				ups.setBeginDate(new Date());
				ups.setCreatedBy(userId);
				ups.setCreatedTime(new Date());
				ups.setEndDate(new Date());
				ups.setIsvaild(1);
				ups.setProductServiceType(UserProductServiceConstants.productServiceType.user.getType());
				ups.setUserId(userId);
				int bool = userProductServiceMapper.insert(ups);
				logger.info("======================creadeUserProductService end :bool="+bool+"======================");
			} catch (Exception e) {
				// TODO: handle exception
				logger.info("======================creadeUserProductService error: "+e.getMessage());
				logger.error("======================creadeUserProductService error: "+e.getMessage());
			}
		}
	}
	/**
	 * 
	 * @param userInfo
	 * @param activityId 活动id
	 * @param
	 * @param shareUserInfo 分享者实体
	 * @return
	 */
	public boolean sendCounpon(UserInfo userInfo, Integer activityId, UserInfo shareUserInfo) {
//		UserInfo userInfo = userInfoMapper.selectByOpenid(openId);//当前被分享者
//		UserInfo shareUserInfo = userInfoMapper.selectByOpenid(shareOpenid);//分享者
		//给邀请人和被邀请人发放优惠券
		logger.info(userInfo.getId()+" : user id and shareid value is :"+ shareUserInfo.getId());
		couponService.addCouponDetailByActivityId(activityId, userInfo.getId());
		//向活动明细表插入参与活动的人插入数据   被分享者名字  发起邀请的id   被分享的id  活动id
		ActivityUser aUser = this.initActiveMap(userInfo.getNickName(), shareUserInfo.getId(),  userInfo.getId(), activityId);
		activityUserMapper.insertSelective(aUser);
		if(userInfo.getInviterUserid() ==  null || userInfo.getInviterUserid() == 0){
			userInfo.setInviterUserid(shareUserInfo.getId());
			int bool = userInfoMapper.updateSelectiveById(userInfo);//更新被邀请者
			return bool > 0;
		} else {
			return true;
		}
	}
	
	
	/**
	 * 判断该用户是否是新用户
	 * 判断逻辑：
	 * 1.该用户未在我们平台购买过课程产品
	 * 2.该用户未领取过activityId 活动的优惠券
	 * 3.该用户没有成为会员的记录
	 * openId： 当前被分享者的openId
	 * userInfo : 如果是全新用户传null 
	 * activityId: 活动
	 * shareOpenid： 分享者openId
	 * 1 ： 扫码关注   获取openid 查这个用户是否存在  如果存在
	 */
	@Override
	public  Map<String,Object> isNewCustomOrInsert(String openId, UserInfo userInfo, Integer activityId, UserInfo shareUserInfo) {
		logger.info("============================ queryUserExistsOrIsHaveCoupon start : openId="+userInfo+" activityId="+activityId+"===");
		logger.info("isNewCustomOrInsert start dateTime:"+new Date());
		Long startTime = System.currentTimeMillis();
		Map<String,Object> parMap = new HashMap<>();
//		userInfo = userInfoMapper.selectByOpenid(openId);
		parMap.put("msg", "未领取该活动的优惠券!");
		parMap.put("bool", true);
		try {
			if(shareUserInfo.getOpenid().equals(userInfo.getOpenid())) { //自己点自己的链接不能继续送券
				parMap.put("msg", "");
				parMap.put("bool", false);
				return parMap;
			}
			// 判断该用户是否有过购买行为	
			Integer countOrder = orderInfoMapper.queryUserOrderIsCompleted(userInfo.getId());
			if(countOrder > 0){
				parMap.put("msg", "您购买过课程订单");
				parMap.put("bool", false);
				return parMap;
			}
			// 判断该用户是否领取过该活动的优惠券
			ActivityInfo at = activityInfoMapper.selectById(activityId);
			if(at != null){
				String coupons = at.getInviteCouponId();
				List<String> lists = Arrays.asList(coupons.split("#"));
				Integer count = couponDetailMapper.queryUserHasCount(userInfo.getId(), lists);
				if(count > 0){
					parMap.put("msg", "您已经领取过该活动的优惠券！");
					parMap.put("bool", false);
					return parMap;
				}
			}
			// 没有成为会员过的记录
			List<VipPurchaseLog> vipLogList = vipPurchaseLogMapper.queryVipPurchaseLogByUserId(userInfo.getId());
			if(vipLogList.size() > 0){
				parMap.put("msg", "您已有过会员记录！");
				parMap.put("bool", false);
				return parMap;
			}
			//没有下单行为没有领过券 进行送券
			this.sendCounpon(userInfo, activityId, shareUserInfo);//全新用户直接送券
			
		} catch (Exception e) {
			parMap.put("bool", false);
			logger.info("==================== queryUserExistsOrIsHaveCoupon error: "+e.getMessage()+"==============");
		}
		Long endTime = System.currentTimeMillis();
		logger.info("isNewCustomOrInsert end dateTime:"+(endTime - startTime)/1000 );
		logger.info("==================== queryUserExistsOrIsHaveCoupon msg: msg"+parMap.get("msg")+" ==============");
		logger.info("==================== queryUserExistsOrIsHaveCoupon end ==============");
		return parMap;
	}
	
	/**
	 * 面对面分享获取临时二维码
	 */
	@Override
	public Map<String, Object> getQRSceneImgUrl(Integer userId, Integer activityId) {
		Map<String, Object> parMap = new HashMap<>();
		//QrCodeUtil qc = new QrCodeUtil();
		Token token =  tokenMapper.selectTokenByKey(TokenConstants.ACCESS_TOKEN_KEY);
		parMap = QrCodeUtils.createQRSCENE(token.getToken(), userId+"");
		return parMap;
	}

	@Override
	public boolean checkUserIsBlacklistUser(Integer userId) {
		// TODO Auto-generated method stub
		if(userInfoMapper.checkUserIsBlacklistUser(userId) > 0){
			return true;
		}
		return false;
	}
	
	/**
	 * 获取用户信息二维码
	 * 
	 */
	@Override
	public Map<String, Object> getUserDataQRCode(Integer userId , String QRCodeType) {
		Map<String, Object> parMap = new HashMap<>();
		Token token =  tokenMapper.selectTokenByKey(TokenConstants.ACCESS_TOKEN_KEY);
		String jumpUrl = String.valueOf(PropertiesUtil.get("get_user_data_url")).trim();
		jumpUrl = jumpUrl.replace("{0}", userId+"").replace("{1}", QRCodeType);
		try {
			
			BufferedImage image = QRCodeUtil.toBufferedImage(jumpUrl, 200, 200);
			ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		    ImageOutputStream imageOutput = ImageIO.createImageOutputStream(byteArrayOutputStream);
		    ImageIO.write(image, "png", imageOutput);
		    InputStream inputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
			
		    // 生成BAS64 的字符串
			String QRCodeUrl = "data:image/gif;base64,"+ImageUtils.GetImageStr(inputStream);
			// 不需要上传到OSS 这里就注释掉 
//			String ossUrl = QRCodeUtil.createSignInQRCode(jumpUrl);
			parMap.put("QRCodeUrl", QRCodeUrl);
		} catch ( WriterException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			logger.error("=================== getUserDataQRCode error:"+e.toString()+e.getCause(),e);
		} 
		
		return parMap;
	}
	
	/**
	 * 用户用户信息和餐券信息
	 * 
	 * 这里只有管理人员才能看得到
	 */
	@Override
	public Map<String, Object> getUserInfoAndUserMealData(Integer userId, UserInfo adminUserInfo , String QRCodeType) {
		UserInfo userInfo = this.getUserInfoById(userId);
		SysUser sysUser = sysUserMapper.querySysUserByMobile(adminUserInfo.getMobile());
		Map<String,Object> resultMap = new HashMap<String, Object>();
		
		// 判断是不是系统用户
		if(sysUser == null || (sysUser != null && !"1".equals(sysUser.getStatus())) ) {
			resultMap.put("accountAmt", null);
			resultMap.put("headImg", null);
			resultMap.put("userMealCount", null);
			resultMap.put("msg", "您还不是管理员");
			resultMap.put("isAdmin", false);
			return resultMap;
		}
		
		// 校验权限
		// 餐支付权限
		DataDict payMealRole = dataDictService.queryDataDictByDictTypeAndDictCode("PAY_MEAL_ROLE",
				sysUser.getRoleId().toString());
		// 判断该该角色是否拥有权限 判断其状态是否有效
		if (payMealRole == null || (payMealRole != null && !"1".equals(payMealRole.getStatus()))) {
			resultMap.put("accountAmt", null);
			resultMap.put("headImg", null);
			resultMap.put("userMealCount", null);
			resultMap.put("msg", "你没有餐饮扫码扣款权限！");
			resultMap.put("isAdmin", false);
			return resultMap;
		}

		// 是收营员的时候 门店id是不能为空的
		if (sysUser.getStoreId() == null) {
			resultMap.put("accountAmt", null);
			resultMap.put("headImg", null);
			resultMap.put("userMealCount", null);
			resultMap.put("msg", "没有指定餐饮门店！请联系管理人员添加门店权限");
			resultMap.put("isAdmin", false);
			return resultMap;
		}
		
		// 个人储值卡的二维码 
		if("card".equals(QRCodeType)) {
			resultMap.put("accountAmt", userInfo.getAccountAmt());
			resultMap.put("headImg", userInfo.getHeadImg());
			resultMap.put("nickName", userInfo.getNickName());
			resultMap.put("userMealCount", null);
			resultMap.put("isAdmin", true);
		}else { // 这里暂时预留 
			resultMap.put("accountAmt", userInfo.getAccountAmt());
			resultMap.put("headImg", userInfo.getHeadImg());
			resultMap.put("nickName", userInfo.getNickName());
			resultMap.put("userMealCount", null);
			resultMap.put("isAdmin", true);
		}
		
		return resultMap;
	}

	@Override
	public boolean checkUserHasMealRole(UserInfo userInfo) {
		SysUser sysUser = sysUserMapper.querySysUserByMobile(userInfo.getMobile());
		if(sysUser == null) {
			return false;
		}
		
		// 餐支付权限
		DataDict payMealRole = dataDictService.queryDataDictByDictTypeAndDictCode("PAY_MEAL_ROLE",
				sysUser.getRoleId().toString());

		// 这里只有餐饮权限的同事才有权限
		// 判断该该角色是否拥有权限 判断其状态是否有效
		if (payMealRole == null || (payMealRole != null && !"1".equals(payMealRole.getStatus()))) {
			return false;
		}
		return true;
	}

}
